<?php
/**
 * Gére les déplacements d'unités
 *
 * @version 2.0
 * @author jonathan <jo.link.noir@gmail.com>
 * @date 02-10-2010
 *
 * @exceptions
 * SW_Planet_Exception :
 * 	1 => Planète inexistante
 */
abstract class SW_Move_Units extends SW_Move_Access
{
	/**
	 * Envoie les vaisseaux
	 * @param int $timeRef = null
	 * @return bool|int : si int alors id du mouvement
	 */
	abstract public function send($timeRef = null);


	/** @var SW_Units */
	protected $army;

	/** @var int */
	protected $planetSend;


	/**
	 * @param int $planetSend
	 * @param SW_Units $army
	 * @param array|SW_Move $move
	 */
	public function __construct($planetSend, SW_Units $army, $move)
	{
		parent::__construct($move);
		$this->setUnits($army);
		$this->planetSend = $planetSend;
	}

	/**
	 * @param SW_Units $army
	 */
	public function setUnits(SW_Units $army)
	{
		$this->army = $army;
	}

	/**
	 * @return SW_Units
	 */
	public function getUnits()
	{
		return $this->army;
	}

	/**
	 * Effectue l'actions du mouvement.
	 * @param int $time = null : définit le temps de référence. Si null $time = $_SERVER['REQUEST_TIME']
	 * @return bool|null
	 */
	protected function arrived(SW_Move $move, $time = null)
	{
		///TODO $this->army => $this ?
		return $move->arrive($this->army);
	}

	/**
	 * Effectue runArrive pour chaque mouvements passé. Le retour de runArrive peut-être true : passe au suivant, false : arrête les actions ou null : continue sans passé au mouvement suivant.
	 * @param int $time = null : définit le temps de référence. Si null $time = $_SERVER['REQUEST_TIME']
	 * @return SW_Move|null : retourne le déplacement suivant
	 */
	final public function arrive($time = null)
	{
		$move = $this->begin;
		while ($move)
		{
			if ($move->move->isArrive($time))
			{
				$ret = $this->arrived($move->move);
				if (false === $ret)
					return $move->next;
				if (true === $ret)
					$move = $move->next;
				else if (null !== $ret)
					throw new SW_Move_Units_Exception(get_class($move->move).': error returned value. Accepte true, false or null', 1);
			}
			else
				return $move->move;
		}
		return null;
	}
}